package cn.gs.exchanger.agent;

// @author gs
import cn.gs.reflect.IProxy;
import cn.gs.reflect.ProxyTool;
import java.lang.reflect.Method;
import net.sf.cglib.proxy.MethodProxy;

public class Agent implements IProxy {

    private String id;
    private String server;
    AgentClient manager;
    Class<?> forProxy;

    public Agent(String id, String server, AgentClient manager, Class<?> forProxy) {
        this.id = id;
        this.server = server;
        this.manager = manager;
        this.forProxy = forProxy;
    }

    public Object proxyObject() {
        return ProxyTool.create(this, forProxy);
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        if (Object.class.equals(method.getDeclaringClass())) {
            return method.invoke(this, args);
        } else {
            return manager.invoke(getId(), method.getReturnType(), CAgent.ASK + method.getDeclaringClass().getCanonicalName() + "." + method.getName() + "@" + getServer(), args);
        }
    }

    @Override
    public Object intercept(Object o, Method method, Object[] os, MethodProxy mp) throws Throwable {
        return invoke(o, method, os);
    }

    @Override
    public int hashCode() {
        int hash = 7;
        hash = 23 * hash + (this.id != null ? this.id.hashCode() : 0);
        hash = 23 * hash + (this.server != null ? this.server.hashCode() : 0);
        hash = 23 * hash + (this.manager != null ? this.manager.hashCode() : 0);
        return hash;
    }

    @Override
    public boolean equals(Object obj) {
        if (obj == null) {
            return false;
        }
        if (getClass() != obj.getClass()) {
            return false;
        }
        final Agent other = (Agent) obj;
        if ((this.id == null) ? (other.id != null) : !this.id.equals(other.id)) {
            return false;
        }
        if ((this.server == null) ? (other.server != null) : !this.server.equals(other.server)) {
            return false;
        }
        if (this.manager != other.manager && (this.manager == null || !this.manager.equals(other.manager))) {
            return false;
        }
        return true;
    }

    @Override
    protected void finalize() throws Throwable {
        manager.addRemoveQueue(server, id);
        super.finalize();
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getServer() {
        return server;
    }

    public void setServer(String server) {
        this.server = server;
    }
}
